package main

import (
	"fmt"
	"io/ioutil"
	"log"
	"net/http"
	"os"
	"path"
	"strings"

	"github.com/Jeffail/gabs"
)

var www string = "http://"
var host string

func main() {
	if len(os.Args) != 4 {
		fmt.Println("usage: pdf-spider.exe 192.168.4.248:48801 admin 666666")
		return
	}
	www += os.Args[1]
	host = strings.Replace(os.Args[1], ":", ".", -1)
	println(host)
	url := www + fmt.Sprintf("/api/login?login_name=%s&password=%s", os.Args[2], os.Args[3])

	body, err := post(url, "", "")
	if err != nil {
		fmt.Println("post error:", err.Error())
		return
	}

	js, err := gabs.ParseJSON(body)
	if err != nil {
		fmt.Println("post parse json error:", err.Error())
		return
	}

	if !js.Exists("token") {
		return
	}

	token := js.S("token").Data().(string)

	url = www + "/api/slides?case_no=&slide_no=&slide_type=&status=&page=1&size=200"

	body, err = get(url, token)

	if err != nil {
		fmt.Println("get error:", err.Error())
	}

	js, err = gabs.ParseJSON(body)
	if err != nil {
		log.Println(err)
	}

	x, _ := js.ArrayCount("data")
	for i := 0; i < x; i++ {
		slide, _ := js.ArrayElement(i, "data")
		y, _ := slide.ArrayCount("tasks")
		for j := 0; j < y; j++ {
			task, _ := slide.ArrayElement(j, "tasks")
			fmt.Println(task.S("id").Data().(string))
			download(slide, task, token)
		}
	}
}

func download(slide, task *gabs.Container, token string) {
	params := "task_id=" + task.S("id").Data().(string)
	body, err := post(www+"/api/task/cells", token, params)
	if err != nil {
		fmt.Println("download error:", err.Error())
		return
	}
	js, err := gabs.ParseJSON(body)
	if err != nil {
		fmt.Println(err.Error())
		return
	}
	fmt.Println(js.S("data").Data().(string))
	folderName := path.Join(host)
	username := task.Path("user.login_name").Data().(string)

	if strings.ToLower(username) == "user1" || strings.ToLower(username) == "user3" || strings.ToLower(username) == "user5" {
		username = "User1"
	}

	if strings.ToLower(username) == "user2" || strings.ToLower(username) == "user4" || strings.ToLower(username) == "user6" {
		username = "User2"
	}

	if strings.ToLower(username) == "m1" {
		username = "M1"
	}

	fileName := ""

	// 诊断报告
	//fileName = slide.S("sample_no").Data().(string) + "." + slide.S("slide_type").Data().(string) + "." + username
	//save(folderName, fileName, www+"/"+js.S("data").Data().(string))

	// 准确度报告
	if int(task.Path("user.user_type").Data().(float64)) == 1 {
		body, err = post(www+"/api/slides/PN?task_id="+task.S("id").Data().(string), token, "")
		if err != nil {
			fmt.Println("download error:", err.Error())
			return
		}
		js, err = gabs.ParseJSON(body)
		if err != nil {
			fmt.Println(err.Error())
			return
		}
		fmt.Println(js.S("data").Data().(string))
		fileName = slide.S("sample_no").Data().(string) + "." + slide.S("slide_type").Data().(string) + "." + "M1-" + username

		save(folderName, fileName, www+"/"+js.S("data").Data().(string))
	}
}

func save(folderName, fileName, url string) {
	resp, err := http.Get(url)
	if err != nil {
		panic(err)
	}
	defer resp.Body.Close()

	data, err := ioutil.ReadAll(resp.Body)
	if err != nil {
		panic(err)
	}

	os.MkdirAll(path.Join(folderName), 0755)

	ioutil.WriteFile(path.Join(folderName, fileName+".pdf"), data, 0755)
}

func post(url, token, params string) ([]byte, error) {

	method := "POST"

	payload := strings.NewReader(params)

	client := &http.Client{}
	req, err := http.NewRequest(method, url, payload)

	if err != nil {
		fmt.Println(err)
		return nil, err
	}
	if token != "" {
		req.Header.Add("Authorization", token)
	}
	if params != "" {
		req.Header.Add("Content-Type", "application/x-www-form-urlencoded")
	}
	res, err := client.Do(req)
	if err != nil {
		fmt.Println(err)
		return nil, err
	}
	defer res.Body.Close()

	body, err := ioutil.ReadAll(res.Body)
	if err != nil {
		fmt.Println(err)
		return nil, err
	}

	return body, err

}

func get(url, token string) ([]byte, error) {

	method := "GET"

	client := &http.Client{}
	req, err := http.NewRequest(method, url, nil)

	if err != nil {
		fmt.Println(err)
		return nil, err
	}
	req.Header.Add("Authorization", token)

	res, err := client.Do(req)
	if err != nil {
		fmt.Println(err)
		return nil, err
	}
	defer res.Body.Close()

	body, err := ioutil.ReadAll(res.Body)
	if err != nil {
		fmt.Println(err)
		return nil, err
	}
	fmt.Println(string(body))

	return body, err
}
